//@author A0100088R
//
// **********
//
// filter class receives the currently display
// tasks from logic, and arranges the tasks in 
// the order the user wishes
//
// possible sorts
//		deadline
//		priority
//		time
//		task (alphabetically)
//
// **********

#include "Sorter.h"


Sorter::Sorter(void) {

}


Sorter::~Sorter(void) {

}


//returns the nearer date
Task Sorter::compareDeadline(Task a, Task b) {

	if(a.getDeadline() == EMPTY) {
		return a;
	}

	if(b.getDeadline() == EMPTY) {
		return b;
	}

	if(a.getDateInSeconds() > b.getDateInSeconds()) {
		return b;
	} else {
		return a;
	}
}

// returns the task with higher priority
Task Sorter::comparePriority(Task a, Task b) {
	int aPriority;
	int bPriority;

	if(a.getPriority() == LOW) aPriority = 1;
	if(a.getPriority() == MEDIUM) aPriority = 2;
	if(a.getPriority() == HIGH) aPriority = 3;
	if(b.getPriority() == LOW) bPriority = 1;
	if(b.getPriority() == MEDIUM) bPriority = 2;
	if(b.getPriority() == HIGH) bPriority = 3;

	if(bPriority > aPriority) {
		return b;
	} else if (bPriority < aPriority) {
		return a;
	} else {
		return compareTaskName(a, b);//if same priority, compare Taskname
	}
}

// returns the taskname closest to A
Task Sorter::compareTaskName(Task a, Task b) {
	vector<string> pair;
	pair.push_back(a.getTaskName());
	pair.push_back(b.getTaskName());

	sort(pair.begin(),pair.end());

	if(pair[0] == b.getTaskName()) {
		return b;
	}
	return a;
}
//return task with earlier time
Task Sorter::compareTime(Task a, Task b) {
	int timeA = atoi(a.getTime().substr(0,4).c_str());
	int timeB = atoi(b.getTime().substr(0,4).c_str());

	if(timeB < timeA) {
		return b;
	} else {
		return a;
	}
}

vector<Task> Sorter::start(vector<Task> list) {
	
	if(list.size() <2) return list;

	for(unsigned int i = 0; i < list.size()-1; i++) {
		for(unsigned int j = i+1; j < list.size(); j++) {
			Task temp = compareDeadline(list[i],list[j]);
			
			// if the smaller is not in front, swap
			if(temp.getTaskName() != list[i].getTaskName() || temp.getDateInSeconds() != list[i].getDateInSeconds()) {
				list[j] = list[i];
				list[i] = temp;
			}
		}
	}

	for(unsigned int i = 0; i < list.size()-1; i++) {
		for(unsigned int j = i+1; j < list.size(); j++) {
			if(list[i].getDateInSeconds() == list[j].getDateInSeconds()) {	
					Task temp = compareTime(list[i],list[j]);
					if(temp.getTaskName() != list[i].getTaskName() || temp.getTime() != list[i].getTime()) {
						list[j] = list[i];
						list[i] = temp;
					}			
			}
		}
	}

	for(unsigned int i = 0; i < list.size()-1; i++) {
		for(unsigned int j = i+1; j < list.size(); j++) {
			if(list[i].getDateInSeconds() == list[j].getDateInSeconds() &&					// if deadline same
				list[i].getTime().substr(0,4) == list[j].getTime().substr(0,4)) {	// and if starting time same
				
					Task temp = comparePriority(list[i],list[j]);
					if(temp.getTaskName() != list[i].getTaskName() || temp.getPriority() != list[i].getPriority()) {
						list[j] = list[i];
						list[i] = temp;
					}			
			}
		}
	}

	for(unsigned int i = 0; i < list.size()-1; i++) {
		for(unsigned int j = i+1; j < list.size(); j++) {
			if(list[i].getDateInSeconds() == list[j].getDateInSeconds() && 
				list[i].getTime().substr(0,4) == list[j].getTime().substr(0,4) && 
				list[i].getPriority() == list[j].getPriority()) {
				
					Task temp = compareTaskName(list[i],list[j]);
					if(temp.getTaskName() != list[i].getTaskName()) {
						list[j] = list[i];
						list[i] = temp;
					}			
			}
		}
	}



	return list;
}

vector<Task> Sorter::start(const string & command, vector<Task> list) {

	if (command == DEFAULT) {//sort by deadline, time, priority, alphabet
	for(unsigned int i = 0; i < list.size()-1; i++) {
		for(unsigned int j = i+1; j < list.size(); j++) {
			Task temp = compareDeadline(list[i],list[j]);
			
			// if the smaller is not in front, swap
			if(temp.getTaskName() != list[i].getTaskName() || temp.getDateInSeconds() != list[i].getDateInSeconds()) {
				list[j] = list[i];
				list[i] = temp;
			}
		}
	}

	for(unsigned int i = 0; i < list.size()-1; i++) {
		for(unsigned int j = i+1; j < list.size(); j++) {
			if(list[i].getDateInSeconds() == list[j].getDateInSeconds()) {	
					Task temp = compareTime(list[i],list[j]);
					if(temp.getTaskName() != list[i].getTaskName() || temp.getTime() != list[i].getTime()) {
						list[j] = list[i];
						list[i] = temp;
					}			
			}
		}
	}

	for(unsigned int i = 0; i < list.size()-1; i++) {
		for(unsigned int j = i+1; j < list.size(); j++) {
			if(list[i].getDateInSeconds() == list[j].getDateInSeconds() &&					// if deadline same
				list[i].getTime().substr(0,4) == list[j].getTime().substr(0,4)) {	// and if starting time same
				
					Task temp = comparePriority(list[i],list[j]);
					if(temp.getTaskName() != list[i].getTaskName() || temp.getPriority() != list[i].getPriority()) {
						list[j] = list[i];
						list[i] = temp;
					}			
			}
		}
	}

	for(unsigned int i = 0; i < list.size()-1; i++) {
		for(unsigned int j = i+1; j < list.size(); j++) {
			if(list[i].getDateInSeconds() == list[j].getDateInSeconds() && 
				list[i].getTime().substr(0,4) == list[j].getTime().substr(0,4) && 
				list[i].getPriority() == list[j].getPriority()) {
				
					Task temp = compareTaskName(list[i],list[j]);
					if(temp.getTaskName() != list[i].getTaskName()) {
						list[j] = list[i];
						list[i] = temp;
					}			
			}
		}
	}

	} else if(command == PRIORITY){//sort by priority, deadline, time, alphabet 
	for(unsigned int i = 0; i < list.size()-1; i++) {
		for(unsigned int j = i+1; j < list.size(); j++) {
			Task temp = comparePriority(list[i],list[j]);
			
			// if the smaller is not in front, swap
			if(temp.getTaskName() != list[i].getTaskName() || temp.getPriority() != list[i].getPriority()) {
				list[j] = list[i];
				list[i] = temp;
			}
		}
	}

	for(unsigned int i = 0; i < list.size()-1; i++) {
		for(unsigned int j = i+1; j < list.size(); j++) {
			if(list[i].getPriority() == list[j].getPriority()) {	
					Task temp = compareDeadline(list[i],list[j]);
					if(temp.getTaskName() != list[i].getTaskName() || temp.getDateInSeconds() != list[i].getDateInSeconds()) {
						list[j] = list[i];
						list[i] = temp;
					}			
			}
		}
	}

	for(unsigned int i = 0; i < list.size()-1; i++) {
		for(unsigned int j = i+1; j < list.size(); j++) {
			if(list[i].getPriority() == list[j].getPriority() &&					// if priority same
				list[i].getDateInSeconds() == list[j].getDateInSeconds()) {	// and if starting time same
				
					Task temp = compareTime(list[i],list[j]);
					if(temp.getTaskName() != list[i].getTaskName() || temp.getTime() != list[i].getTime()) {
						list[j] = list[i];
						list[i] = temp;
					}			
			}
		}
	}

	for(unsigned int i = 0; i < list.size()-1; i++) {
		for(unsigned int j = i+1; j < list.size(); j++) {
			if(list[i].getDateInSeconds() == list[j].getDateInSeconds() && 
				list[i].getTime().substr(0,4) == list[j].getTime().substr(0,4) && 
				list[i].getPriority() == list[j].getPriority()) {
				
					Task temp = compareTaskName(list[i],list[j]);
					if(temp.getTaskName() != list[i].getTaskName()) {
						list[j] = list[i];
						list[i] = temp;
					}			
			}
		}
	}
	}else if(command == TIME){//sort by time, deadline, priority, alphabet
	for(unsigned int i = 0; i < list.size()-1; i++) {
		for(unsigned int j = i+1; j < list.size(); j++) {
			Task temp = compareTime(list[i],list[j]);
			
			// if the smaller is not in front, swap
			if(temp.getTaskName() != list[i].getTaskName() || temp.getTime() != list[i].getTime()) {
				list[j] = list[i];
				list[i] = temp;
			}
		}
	}

	for(unsigned int i = 0; i < list.size()-1; i++) {
		for(unsigned int j = i+1; j < list.size(); j++) {
			if(list[i].getTime().substr(0,4) == list[j].getTime().substr(0,4)) {	
					Task temp = compareDeadline(list[i],list[j]);
					if(temp.getTaskName() != list[i].getTaskName() || temp.getDateInSeconds() != list[i].getDateInSeconds()) {
						list[j] = list[i];
						list[i] = temp;
					}			
			}
		}
	}

	for(unsigned int i = 0; i < list.size()-1; i++) {
		for(unsigned int j = i+1; j < list.size(); j++) {
			if(list[i].getDateInSeconds() == list[j].getDateInSeconds() &&					// if deadline same
				list[i].getTime().substr(0,4) == list[j].getTime().substr(0,4)) {	// and if starting time same
				
					Task temp = comparePriority(list[i],list[j]);
					if(temp.getTaskName() != list[i].getTaskName() || temp.getPriority() != list[i].getPriority()) {
						list[j] = list[i];
						list[i] = temp;
					}			
			}
		}
	}

	for(unsigned int i = 0; i < list.size()-1; i++) {
		for(unsigned int j = i+1; j < list.size(); j++) {
			if(list[i].getDateInSeconds() == list[j].getDateInSeconds() && 
				list[i].getTime().substr(0,4) == list[j].getTime().substr(0,4) && 
				list[i].getPriority() == list[j].getPriority()) {
				
					Task temp = compareTaskName(list[i],list[j]);
					if(temp.getTaskName() != list[i].getTaskName()) {
						list[j] = list[i];
						list[i] = temp;
					}			
			}
		}
	}
	}else if(command == TASK){//sort by alphabet, deadline, time, priority
	for(unsigned int i = 0; i < list.size()-1; i++) {
		for(unsigned int j = i+1; j < list.size(); j++) {
			Task temp = compareTaskName(list[i],list[j]);
			
			// if the smaller is not in front, swap
			if(temp.getTaskName() != list[i].getTaskName()) {
				list[j] = list[i];
				list[i] = temp;
			}
		}
	}

	for(unsigned int i = 0; i < list.size()-1; i++) {
		for(unsigned int j = i+1; j < list.size(); j++) {
			if(list[i].getTaskName() == list[j].getTaskName()) {	
					Task temp = compareDeadline(list[i],list[j]);
					if(temp.getTaskName() != list[i].getTaskName() || temp.getDateInSeconds() != list[i].getDateInSeconds()) {
						list[j] = list[i];
						list[i] = temp;
					}			
			}
		}
	}

	for(unsigned int i = 0; i < list.size()-1; i++) {
		for(unsigned int j = i+1; j < list.size(); j++) {
			if(list[i].getTaskName() == list[j].getTaskName() &&					// if Taskname same
				list[i].getDateInSeconds() == list[j].getDateInSeconds()) {	// and if starting time same
				
					Task temp = compareTime(list[i],list[j]);
					if(temp.getTaskName() != list[i].getTaskName() || temp.getTime() != list[i].getTime()) {
						list[j] = list[i];
						list[i] = temp;
					}			
			}
		}
	}

	for(unsigned int i = 0; i < list.size()-1; i++) {
		for(unsigned int j = i+1; j < list.size(); j++) {
			if(list[i].getDateInSeconds() == list[j].getDateInSeconds() && 
				list[i].getTime().substr(0,4) == list[j].getTime().substr(0,4) && 
				list[i].getTaskName() == list[j].getTaskName()) {
				
					Task temp = comparePriority(list[i],list[j]);
					if(temp.getTaskName() != list[i].getTaskName() || temp.getPriority() != list[i].getPriority()) {
						list[j] = list[i];
						list[i] = temp;
					}			
			}
		}
	}
	}else {
		throw exception ("sort type error");
	}


	return list;
}